package com.yenroc.invoice.pojo;

import com.fasterxml.jackson.annotation.JsonFormat;
import com.yenroc.invoice.annotations.Schema;
import com.yenroc.invoice.constant.InvoiceFlagEnum;
import com.yenroc.invoice.constant.InvoiceTypeEnum;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.SuperBuilder;

import javax.validation.constraints.Digits;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;
import java.io.Serializable;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;


/**
 * 数字化电子发票通用信息实体类
 */
@Data
@AllArgsConstructor
@NoArgsConstructor
@SuperBuilder
@Schema(description = "数字化电子发票通用信息实体类")
public class CommonInvoiceDTO implements Serializable {

    private static final long serialVersionUID = 8045457726436710878L;

    /**
     * 发票类型, {@link InvoiceTypeEnum InvoiceTypeEnum}
     */
    @Schema(description = "发票类型, 传01时为数电专票, 传02时为数电普票", example = "01", requiredMode = Schema.RequiredMode.REQUIRED)
    @NotBlank(message = "发票票种不可为空, 取值范围为[01、02], 传01时为数电专票, 传02时为数电普票")
    private String invoiceType;

    @Schema(description = "发票标签")
    private String invoiceTag;

    @Schema(description = "发票号码")
    @NotBlank(message = "发票号码不可为空")
    @Size(min = 20, max = 20, message = "发票号码长度必须为20位")
    private String invoiceNo;

    @Schema(description = "发票日期", example = "1677081600000")
    @NotNull(message = "发票日期不可为空")
    private Long invoiceDate;

    @Schema(description = "税务局代码", requiredMode = Schema.RequiredMode.REQUIRED)
    @NotBlank(message = "税务局代码不可为空")
    private String taxBureauCode;

    @Schema(description = "税务局名称", requiredMode = Schema.RequiredMode.REQUIRED)
    @NotBlank(message = "税务局名称不可为空")
    private String taxBureauName;

    @Schema(description = "购买方名称", requiredMode = Schema.RequiredMode.REQUIRED)
    @NotBlank(message = "购买方名称不可为空")
    private String buyerName;

    @Schema(description = "购买方税号, 开具数字化电子专票时, 购买方税号不可为空")
    @NotBlank(message = "开具数字化电子专票时, 购买方税号不可为空", groups = SpecInvoiceGroup.class)
    private String buyerTaxNo;

    @Schema(description = "销售方名称", requiredMode = Schema.RequiredMode.REQUIRED)
    @NotBlank(message = "销售方名称不可为空")
    private String sellerName;

    @Schema(description = "销售方税号", requiredMode = Schema.RequiredMode.REQUIRED)
    @NotBlank(message = "销售方税号不可为空")
    private String sellerTaxNo;

    @Schema(description = "销售方地址")
    private String sellerAddr;

    @Schema(description = "销售方电话")
    private String sellerTelNum;

    @Schema(description = "销售方开户行")
    private String sellerBankName;

    @Schema(description = "销售方银行账号")
    private String sellerBankAccNum;

    @Schema(description = "购买方地址")
    private String buyerAddr;

    @Schema(description = "开票人", requiredMode = Schema.RequiredMode.REQUIRED)
    @NotBlank(message = "开票人不可为空")
    private String drawer;

    @Schema(description = "备注")
    private String remark;

    /**
     * 蓝字发票标志, {@link InvoiceFlagEnum InvoiceStatusEnum}
     * 蓝字发票标志, 0：蓝字发票；1：红字发票
     */
    @Schema(description = "蓝字发票标志, 传0时为蓝字发票, 传1时为红字发票", example = "0", requiredMode = Schema.RequiredMode.REQUIRED)
    @NotBlank(message = "蓝字发票标志不可为空, 取值范围为[0、1], 传0时为蓝字发票, 传1时为红字发票")
    private String invoiceFlag;

    @Schema(description = "合计[金额]", requiredMode = Schema.RequiredMode.REQUIRED)
    @NotNull(message = "合计金额不可为空")
    private BigDecimal totalAmount;

    @Schema(description = "合计[税额]", requiredMode = Schema.RequiredMode.REQUIRED)
    @NotNull(message = "合计税额不可为空")
    private BigDecimal totalTax;

    @Schema(description = "价税合计", requiredMode = Schema.RequiredMode.REQUIRED)
    @NotNull(message = "价税合计不可为空")
    @Digits(integer = 8, fraction = 2, message = "价税合计值必须是整数位不超过8位, 小数位不超过2位的数字")
    @JsonFormat(shape = JsonFormat.Shape.STRING)
    private BigDecimal totalPriceTaxAmount;

    @Schema(description = "被红冲蓝字数电发票号码")
    private String originalInvoiceCode;

    @Schema(description = "红字发票信息确认单编号")
    private String creditNoteNumber;

    interface BlueInvoiceGroup {
    }

    interface RedInvoiceGroup {
    }

    interface CommonInvoiceGroup {
    }

    interface SpecInvoiceGroup {
    }

}